package plgcore

import (
	"dgo/MyProj/PrjConf"
	"dgo/MyProj/PrjHttpUtils"
	"dgo/goutils/utils"
	"dgo/plg/plgbase"
	"fmt"
	"gitee.com/ymofen/gobase/golog"
	"gitee.com/ymofen/supervalue"
	"time"
)

/**
  通知插件
*/

type ProjNotifyPlug struct {
	plgbase.PlgBase
	notifycnt         int
	replyOkFlag       int
	replyTopic        string
	notifyTopic       string
	lastSend          string
	lastReply         string
	monitorPlgId      string
	monitorPlgQryType int
	monitorPlgLastQry string
	timer             *utils.Timer
	ex                *plgbase.InnerEx
}

func (this *ProjNotifyPlug) checkMonitorPlg() {
	if len(this.monitorPlgId) == 0 {
		return
	}

	plg := plgbase.FindPluginByID(this.monitorPlgId)
	if plg == nil {
		return
	}
	if ok, v0 := utils.TryGetValue(plg, this.monitorPlgQryType); ok {
		if utils.GetBoolValue(v0, false) {
			this.replyOkFlag = 1
		}
		this.monitorPlgLastQry = fmt.Sprintf("[%s]%v", utils.NowString(), v0)
	}
}

/*
**

	响应HttpStatus请求
	http://127.0.0.1:6061/plug/vrs-8001/status?type=1
*/
func (this *ProjNotifyPlug) OnHttpStatus(rec *PlgHttpRec) (rval interface{}, errcode int, err error) {
	itype := rec.QryAsInt("type", 0)
	if itype == 99 {
		json := wrapper.NewSVObject()
		json.SetKeyValue("ex", this.ex.StatusString())
		json.SetKeyValue("plugDNA", this.PlugDNA)
		json.SetKeyValue("replyOkFlag", this.replyOkFlag)
		json.SetKeyValue("notifyTopic", this.notifyTopic)
		json.SetKeyValue("notify-n", this.notifycnt)
		json.SetKeyValue("lastSend", this.lastSend)
		json.SetKeyValue("lastReply", this.lastReply)
		json.SetKeyValue("monitor-plg", fmt.Sprintf("id:%s, type:%d, last:%s", this.monitorPlgId, this.monitorPlgQryType, this.monitorPlgLastQry))
		json.SetKeyValue("now", utils.NowString())
		PrjHttpUtils.JSON2TableRec(rec.RespW, "", json.String())
	} else if itype == 1 {
		this.replyOkFlag = 0
		rec.ResponseJSONValues("code", 0, "replyflag", this.replyOkFlag)
	} else {
		var sb utils.BytesBuilder
		PrjHttpUtils.AppendIndexBody(&sb, "status", "status?type=99")
		PrjHttpUtils.AppendIndexBody(&sb, "reset2notify", "status?type=1")
		PrjHttpUtils.ResponseBodyHtml(rec.RespW, sb.String())
	}
	return
}

/*
**

	{
	  "id":"startup",
	  "type":"core.notify",
	  "conf":{
	     "input":{
	         "id":"", "templ":{}
	      },
	     "topic":"xxx",
	     "reply":"",    // 响应主题, 匹配dna
	     "monitor-plg":"xxxx",   // 查询monitor-plg 状态 是否OK
	     "monitor-plg-qrytype":"1",  //查询时 带的参数  默认是0

	   }
	}

// reply 和monitor-plg 二选一设定一个
*/
func (this *ProjNotifyPlug) ReloadConf(conf *wrapper.SuperValue) error {
	isChanged := false
	this.ex.ReloadConf(conf.ValueByName("input"))
	if this.ex.ConfIsChanged() {
		isChanged = true
	}

	if this.timer == nil {
		this.timer = utils.NewTimer()
		this.timer.OnTimer = func(tag interface{}) {
			this.checkMonitorPlg()
			topic := plgbase.ReplacePlaceholder(this.notifyTopic)
			if len(topic) > 0 && this.replyOkFlag == 0 {
				this.ex.SendTopic(topic, func(json *wrapper.SuperValue) {
					this.notifycnt++
					json.SetKeyValues("plugid", this.PlugId, "dna", this.PlugDNA, "cnt", this.notifycnt, "uuid", PrjConf.APP_UUID)
					this.lastSend = fmt.Sprintf("[%s]%s", utils.NowString(), json.String())
				})
			}
		}
		this.timer.ConfigInterval(time.Second*30, 0)
	}

	conf.CheckExistsStrFunc("monitor-plg", func(strv string) {
		if this.monitorPlgId != strv {
			this.monitorPlgId = strv
			isChanged = true
		}
	})

	conf.CheckExistsIntFunc("monitor-plg-qrytype", func(val int64) {
		if this.monitorPlgQryType != int(val) {
			this.monitorPlgQryType = int(val)
			isChanged = true
		}
	})

	conf.CheckExistsStrFunc("reply", func(strv string) {
		if this.replyTopic != strv {
			this.replyTopic = strv
			this.ex.UnSubscribePre()
			this.ex.Subscribe(plgbase.ReplacePlaceholder(this.replyTopic), func(sender interface{}, channelid string, subscribeid interface{}, data interface{}, tag interface{}, isBreak *bool) bool {
				if json, ok := data.(*wrapper.SuperValue); ok {
					this.lastReply = fmt.Sprintf("[%s]%s", utils.NowString(), json.String())
					if json.IntByName("dna", -1) == int(this.PlugDNA) {
						this.replyOkFlag = 1
						golog.Infof("响应OK:%s", json.AsJSONString(false))
					}
				}
				return true
			})
			isChanged = true
		}
	})

	conf.CheckExistsStrFunc("topic", func(strv string) {
		if this.notifyTopic != strv {
			this.notifyTopic = strv
			isChanged = true
		}
	})

	if isChanged {
		golog.Debugf("changed")
		this.replyOkFlag = 0 // 置零, 重新启动
	}

	return nil
}

func (this *ProjNotifyPlug) OnObjectNotify(sender interface{}, notifytype int, data interface{}) (rval interface{}, err error) {
	if notifytype == utils.NOTIFY_TYPE_SETCONF {
		if conf, ok := data.(*wrapper.SuperValue); ok {
			err = this.ReloadConf(conf)
		} else {
			err = fmt.Errorf("非法的JSON配置")
		}
	} else if notifytype == utils.NOTIFY_TYPE_RELEASE {
		this.ReleaseFlag = 1
		this.ex.Release()
		this.timer.Close()
	}
	return
}

func CreateProjNotifyPlugFunc(args ...interface{}) (rval interface{}, err error) {
	obj := &ProjNotifyPlug{}
	if len(args) > 0 {
		if str, ok := args[0].(string); ok {
			obj.PlugId = str
		}
	}
	obj.CheckDNA()
	obj.ex = plgbase.NewInnerEx()
	rval = obj
	return
}
